home *** CD-ROM | disk | FTP | other *** search
/ Compendium Deluxe 2 / LSD and 17bit Compendium Deluxe - Volume II.iso / a / prog / cprog / tdddconv.lha / readtddd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-12  |  17.7 KB  |  638 lines

  1. /* ReadTDDD.c - read a TDDD (Three Dimension Data Decription) file
  2.  *            - and write a TTDDD text file with its contents
  3.  *            - written by Glenn M. Lewis - 9/4/91
  4.  */
  5.  
  6. static char rcs_id[] = "$Id: readtddd.c,v 1.7 1991/10/14 15:09:18 glewis Exp glewis $";
  7.  
  8. #include <stdio.h>
  9. #include <ctype.h>
  10. #include "ttdddlib.h"
  11. #define MAXLINE 132
  12.  
  13. static void process_DESC();
  14. static OBJECT *process_EXTR();
  15. static void process_INFO();
  16. static void process_OBJ();
  17.  
  18. /* Here are a few necessary utilities */
  19.  
  20. static void get_name(name, size, world)
  21. register char  *name;
  22. register int size;
  23. WORLD *world;
  24. {
  25.     while (size--) *name++ = fgetc(world->inp);
  26.     *name = '\0';
  27. }
  28.  
  29. static BYTE get_BYTE(world)
  30. WORLD *world;
  31. {
  32.     return((BYTE)fgetc(world->inp));
  33. }
  34.  
  35. static UBYTE get_UBYTE(world)
  36. WORLD *world;
  37. {
  38.     return((UBYTE)fgetc(world->inp));
  39. }
  40.  
  41. static WORD get_WORD(world)
  42. WORLD *world;
  43. {
  44.     WORD tmp = (WORD)get_UBYTE(world)<<8;
  45.     return(tmp|get_UBYTE(world));
  46. }
  47.  
  48. static UWORD get_UWORD(world)
  49. WORLD *world;
  50. {
  51.     UWORD tmp = (UWORD)get_UBYTE(world)<<8;
  52.     return(tmp|get_UBYTE(world));
  53. }
  54.  
  55. static ULONG get_ULONG(world)
  56. WORLD *world;
  57. {
  58.     ULONG tmp = (ULONG)get_UWORD(world)<<16;
  59.     return(tmp|get_UWORD(world));
  60. }
  61.  
  62. static float get_FRACT(world)    /* This sets the precision to 10^(-3) */
  63. WORLD *world;
  64. {
  65.     register float whole, fract;
  66.  
  67.     whole =  (float)get_WORD(world);
  68.     fract = ((float)get_UWORD(world))/65536.0;
  69.     return(whole+fract);
  70. }
  71.  
  72. static void stuff_XYZ(st, world)
  73. XYZ_st *st;
  74. WORLD *world;
  75. {
  76.     st->val[0] = get_FRACT(world);
  77.     st->val[1] = get_FRACT(world);
  78.     st->val[2] = get_FRACT(world);
  79. }
  80.  
  81. static void stuff_RGB(st, world)
  82. RGB_st *st;
  83. WORLD *world;
  84. {
  85.     st->val[0] = get_UBYTE(world);
  86.     st->val[1] = get_UBYTE(world);
  87.     st->val[2] = get_UBYTE(world);
  88. }
  89.  
  90. /********************/
  91. /* The MAIN section */
  92. /********************/
  93.  
  94. int already_read_header = 0;
  95. unsigned char header_storage[13];
  96.  
  97. WORLD *read_World(file)
  98. FILE *file;
  99. {
  100.     int i;
  101.     for (i=0; i<4; i++) header_storage[i] = fgetc(file);
  102.     already_read_header = 4;
  103.     if (strncmp(header_storage, "FORM", 4)==0) {
  104.         while (i<12) header_storage[i++] = fgetc(file);
  105.         already_read_header = 12;
  106.         if (strncmp(&header_storage[8], "TDDD", 4)==0) return(read_TDDD(file));
  107.         /* BAD IFF */
  108.         header_storage[12] = 0;
  109.         fprintf(stderr, "ERROR! Unknown FORM: '%s'\n", &header_storage[8]);
  110.         return(0);
  111.     } else {
  112.         return(read_TTDDD(file));
  113.     }
  114. }
  115.  
  116. WORLD *read_TDDD(file)
  117. FILE *file;
  118. {
  119.     register ULONG i, len, size;
  120.     WORLD *world;
  121.     char name[5];
  122.  
  123.     if (!file) return(0L);    /* File not open */
  124.  
  125.     if (!(world = (WORLD*)malloc(sizeof(WORLD)))) { OUT_MEM("WORLD"); }
  126.     bzero((char*)world, sizeof(WORLD));
  127.     world->inp = file;
  128.  
  129.     if (!already_read_header) {
  130.         /* Parse the IFF TDDD file */
  131.         get_name(name, 4, world);
  132.         if (strcmp(name, "FORM") != 0) {
  133.             fprintf(stderr, "ERROR: Input is not an IFF file.\n"); exit(-1); }
  134.         if (!(len = get_ULONG(world))) {
  135.             fprintf(stderr, "ERROR: Bad FORM length in IFF file.\n"); exit(-1); }
  136.         get_name(name, 4, world);
  137.         if (strcmp(name, "TDDD") != 0) {
  138.             fprintf(stderr, "ERROR: IFF file is not a TDDD file.\n"); exit(-1); }
  139.     } else {
  140.         len =    (header_storage[4]<<24) | (header_storage[5]<<16) |
  141.                 (header_storage[6]<< 8) | (header_storage[7]    );
  142.         already_read_header = 0;
  143.     }
  144.     len -= 4;
  145.  
  146. /* Here is the main loop: */
  147.     while (len>0) {
  148.         get_name(name, 4, world);
  149.         size = get_ULONG(world);
  150.         len -= 8;
  151.         if (strcmp(name, "INFO")==0) process_INFO(size, world);
  152.         else
  153.         if (strcmp(name, "OBJ ")==0) process_OBJ(size, world);
  154.         else {
  155.             fprintf(stderr, "Warning: Unknown sub-chunk: '%s'...skipped\n",name);
  156.             for (i=size; i--; ) fgetc(world->inp);                /* Skip this section */
  157.         }
  158.         if ((size % 2) == 1) { fgetc(world->inp); len--; }    /* Skip odd byte */
  159.         len -= size;
  160.     }
  161.  
  162. /* All done. */
  163.     return(world);
  164. }
  165.  
  166. static void process_INFO(len, world)
  167. register ULONG len;
  168. WORLD *world;
  169. {
  170.     register INFO *info;
  171.     register ULONG i, size;
  172.     char name[5];
  173.  
  174.     if (world->info) {
  175.         fputs("ERROR: More than one INFO chunk!\n", stderr); exit(-1); }
  176.     if (!(info = world->info = (INFO*)malloc(sizeof(INFO)))) { OUT_MEM("INFO"); }
  177.     bzero((char*)world->info, sizeof(INFO));
  178.  
  179.     while (len>0) {
  180.         get_name(name, 4, world);
  181.         size = get_ULONG(world);
  182.         len -= 8;
  183.         if (strcmp(name, "BRSH")==0) {
  184.             i = get_UWORD(world);
  185.             if (i<0 || i>7) { i=0; fputs("BRSH error.\n", stderr); }
  186.             get_name(info->brsh[i], 80, world);
  187.         } else
  188.         if (strcmp(name, "STNC")==0) {
  189.             i = get_UWORD(world);
  190.             if (i<0 || i>7) { i=0; fputs("STNC error.\n", stderr); }
  191.             get_name(info->stnc[i], 80, world);
  192.         } else
  193.         if (strcmp(name, "TXTR")==0) {
  194.             i = get_UWORD(world);
  195.             if (i<0 || i>7) { i=0; fputs("TXTR error.\n", stderr); }
  196.             get_name(info->txtr[i], 80, world);
  197.         } else
  198.         if (strcmp(name, "OBSV")==0) {
  199.             if (!info->obsv) info->obsv=(OBSV*)malloc(sizeof(OBSV));
  200.             if (!info->obsv) { OUT_MEM("OBSV"); }
  201.             stuff_XYZ(&info->obsv->came, world);
  202.             stuff_XYZ(&info->obsv->rota, world);
  203.             info->obsv->foca = get_FRACT(world);
  204.         } else
  205.         if (strcmp(name, "OTRK")==0) {
  206.             get_name(info->otrk, 18, world);
  207.         } else
  208.         if (strcmp(name, "OSTR")==0) {
  209.             if (!info->ostr) info->ostr=(STRY*)malloc(sizeof(STRY));
  210.             if (!info->ostr) { OUT_MEM("OSTR"); }
  211.             get_name(info->ostr->path, 18, world);
  212.             stuff_XYZ(&info->ostr->tran, world);
  213.             stuff_XYZ(&info->ostr->rota, world);
  214.             stuff_XYZ(&info->ostr->scal, world);
  215.             info->ostr->info = get_UWORD(world);
  216.         } else
  217.         if (strcmp(name, "FADE")==0) {
  218.             if (!info->fade) info->fade=(FADE*)malloc(sizeof(FADE));
  219.             if (!info->fade) { OUT_MEM("FADE"); }
  220.             info->fade->at = get_FRACT(world);
  221.             info->fade->by = get_FRACT(world);
  222.             fgetc(world->inp);        /* Skip a byte */
  223.             stuff_RGB(&info->fade->to, world);
  224.         } else
  225.         if (strcmp(name, "SKYC")==0) {
  226.             if (!info->skyc) info->skyc=(SKYC*)malloc(sizeof(SKYC));
  227.             if (!info->skyc) { OUT_MEM("SKYC"); }
  228.             fgetc(world->inp);        /* Skip a byte */
  229.             stuff_RGB(&info->skyc->hori, world);
  230.             fgetc(world->inp);        /* Skip a byte */
  231.             stuff_RGB(&info->skyc->zeni, world);
  232.         } else
  233.         if (strcmp(name, "AMBI")==0) {
  234.             if (!info->ambi) info->ambi=(RGB_st*)malloc(sizeof(RGB_st));
  235.             if (!info->ambi) { OUT_MEM("AMBI"); }
  236.             fgetc(world->inp);        /* Skip a byte */
  237.             stuff_RGB(info->ambi, world);
  238.         } else
  239.         if (strcmp(name, "GLB0")==0) {
  240.             if (!info->glb0) info->glb0=(BYTE*)malloc(8*sizeof(BYTE));
  241.             if (!info->glb0) { OUT_MEM("GLB0"); }
  242.             for (i=0; i<8; i++)
  243.                 info->glb0[i] = get_UBYTE(world);
  244.         } else {
  245.             fprintf(stderr, "WARNING: I don't know how to process the INFO sub-sub-chunk: '%s'\n", name);
  246.             for (i=size; i--; ) fgetc(world->inp);                /* Skip this section */
  247.         }
  248.         if ((size % 2) == 1) { fgetc(world->inp); len--; }    /* Skip odd byte */
  249.         len -= size;
  250.     }
  251. }
  252.  
  253. static void process_OBJ(len, world)
  254. register ULONG len;
  255. WORLD *world;
  256. {
  257.     register ULONG i, size;
  258.     register OBJECT *p;
  259.     char name[5];
  260.     int depth=0;
  261.  
  262.     while (len>0) {
  263.         get_name(name, 4, world);
  264.         size = get_ULONG(world);
  265.         len -= 8;
  266.         if (strcmp(name, "EXTR")==0) {
  267.             p = process_EXTR(size, create_object(), world);
  268.             if (world->curobj) {
  269.                 world->curobj->next = p;
  270.                 p->parent = world->curobj->parent;
  271.             } else {
  272.                 world->object = p;
  273.                 p->parent = 0;
  274.             }
  275.             world->curobj = p;
  276.         } else if (strcmp(name, "DESC")==0) {
  277.             p = create_object();
  278.             if (world->num_DESC > world->num_TOBJ+depth) {  /* This is a child */
  279.                 depth++;    /* Down one in the hierarchy */
  280.                 world->curobj->child = p;
  281.                 p->parent = world->curobj;
  282.             } else {
  283.                 if (world->curobj) {
  284.                     world->curobj->next = p;
  285.                     p->parent = world->curobj->parent;
  286.                 } else {
  287.                     world->object = p;
  288.                     p->parent = 0;
  289.                 }
  290.             }
  291.             world->curobj = p;
  292.             process_DESC(size, &p->desc, world);
  293.         } else if (strcmp(name, "TOBJ")==0) {
  294.             world->num_TOBJ++;
  295.             if (world->num_TOBJ > world->num_DESC) {
  296.                 fprintf(stderr, "Warning: TOBJ without DESC.  Ignored.\n");
  297.             }
  298.             if (world->num_TOBJ+depth > world->num_DESC) {  /* Up a level */
  299.                 depth--;
  300.                 world->curobj=world->curobj->parent;
  301.             }
  302.         } else {
  303.             fprintf(stderr, "WARNING: I don't know how to process the OBJ sub-sub-chunk: '%s'\n", name);
  304.             for (i=size; i--; ) fgetc(world->inp);                /* Skip this section */
  305.         }
  306.         if ((size % 2) == 1) { fgetc(world->inp); len--; }    /* Skip odd byte */
  307.         len -= size;
  308.     }
  309. }
  310.  
  311. static OBJECT *process_EXTR(len, obj, world)
  312. register ULONG len;
  313. OBJECT *obj;
  314. WORLD *world;
  315. {
  316.     register ULONG i, size;
  317.     register EXTR *extr;
  318.     register OBJECT *p;
  319.     char name[5];
  320.     MTRX *mtrx;
  321.     WORLD *new;
  322.     FILE *newinp;
  323.  
  324.     if (!(extr = obj->extr = (EXTR*)malloc(sizeof(EXTR))))
  325.         { OUT_MEM("EXTR"); }
  326.     bzero((char*)extr, sizeof(EXTR));
  327.     mtrx = &extr->mtrx;
  328.     /* Initialize structure */
  329.     mtrx->tran.val[0]  = mtrx->tran.val[1]  = mtrx->tran.val[2]  = 0.0;
  330.     mtrx->scal.val[0]  = mtrx->scal.val[1]  = mtrx->scal.val[2]  = 1.0;
  331.     mtrx->rota1.val[1] = mtrx->rota1.val[2] = 0.0;
  332.     mtrx->rota2.val[0] = mtrx->rota2.val[2] = 0.0;
  333.     mtrx->rota3.val[0] = mtrx->rota3.val[1] = 0.0;
  334.     mtrx->rota1.val[0] = mtrx->rota2.val[1] = mtrx->rota3.val[2] = 1.0;
  335.  
  336.     while (len>0) {
  337.         get_name(name, 4, world);
  338.         size = get_ULONG(world);
  339.         len -= 8;
  340.         if (strcmp(name, "MTRX")==0) {
  341.             stuff_XYZ(&mtrx->tran, world);
  342.             stuff_XYZ(&mtrx->scal, world);
  343.             stuff_XYZ(&mtrx->rota1, world);
  344.             stuff_XYZ(&mtrx->rota2, world);
  345.             stuff_XYZ(&mtrx->rota3, world);
  346.         } else
  347.         if (strcmp(name, "LOAD")==0) {
  348.             get_name(extr->filename, 80, world);
  349.         } else {
  350.             fprintf(stderr, "WARNING: I don't know how to process the OBJ sub-sub-chunk: '%s'\n", name);
  351.             for (i=size; i--; ) fgetc(world->inp);                /* Skip this section */
  352.         }
  353.         if ((size % 2) == 1) { fgetc(world->inp); len--; }    /* Skip odd byte */
  354.         len -= size;
  355.     }
  356.     /* Now, load in the external object */
  357.     if (!(newinp=fopen(extr->filename, "r"))) {
  358.         fprintf(stderr, "Can't load in EXTR object: '%s'... ignored.\n",
  359.             extr->filename);
  360.         return(obj);
  361.     }
  362.     new = read_World(newinp);
  363.     fclose(newinp);
  364.     /* scale, rotate, and translate new object hierarchy */
  365.     for (p=new->object; p; p=p->next)
  366.         move_extr(p, mtrx);
  367.     /* Free up unused memory */
  368.     free((char*)obj->extr);
  369.     free((char*)obj);
  370.     obj = new->object;
  371.     free((char*)new);
  372.     return(obj);
  373. }
  374.  
  375. static UBYTE defclst[3], defrlst[3], deftlst[3], defspc1[3];
  376.  
  377. void malloc_arrays(i, desc)
  378. register int i;
  379. register DESC *desc;
  380. {
  381.     if (!desc->fcount) {
  382.         desc->fcount = i;
  383. if (!(desc->face=(UWORD*)malloc(3*desc->fcount*sizeof(UWORD))))OUT_MEM((char*)0);
  384. if (!(desc->clst=(UBYTE*)malloc(3*desc->fcount*sizeof(UBYTE))))OUT_MEM((char*)0);
  385. if (!(desc->rlst=(UBYTE*)malloc(3*desc->fcount*sizeof(UBYTE))))OUT_MEM((char*)0);
  386. if (!(desc->tlst=(UBYTE*)malloc(3*desc->fcount*sizeof(UBYTE))))OUT_MEM((char*)0);
  387.         /* Initialize arrays */
  388.         for (i=0; i<3*desc->fcount; i+=3) {
  389.             desc->face[i]   = desc->face[i+1] = desc->face[i+2] = 0;
  390.             desc->clst[i]   = defclst[0];
  391.             desc->clst[i+1] = defclst[1];
  392.             desc->clst[i+2] = defclst[2];
  393.             desc->rlst[i]   = defrlst[0];
  394.             desc->rlst[i+1] = defrlst[1];
  395.             desc->rlst[i+2] = defrlst[2];
  396.             desc->tlst[i]   = deftlst[0];
  397.             desc->tlst[i+1] = deftlst[1];
  398.             desc->tlst[i+2] = deftlst[2];
  399.         }
  400.     } else if (i != desc->fcount) {
  401.         fprintf(stderr, "ERROR: FACE and [C|R|T]LST 'Count' values inconsistant.\n");
  402.         OUT_MEM((char*)0);
  403.     }
  404. }
  405.  
  406. static void process_DESC(len, orig, world)
  407. register ULONG len;
  408. DESC **orig;
  409. WORLD *world;
  410. {
  411.     register ULONG size;
  412.     register DESC *desc;
  413.     register int i, j;
  414.     char name[5];
  415.  
  416.     if (!(desc = *orig = (DESC*)malloc(sizeof(DESC))))
  417.         { OUT_MEM("DESC"); }
  418.     bzero((char*)desc, sizeof(DESC));
  419.  
  420.     /* Set up defaults: */
  421.     defclst[0] = defclst[1] = defclst[2] = 240; /* TS default */
  422.     defrlst[0] = defrlst[1] = defrlst[2] = 0;
  423.     deftlst[0] = deftlst[1] = deftlst[2] = 0;
  424.     defspc1[0] = defspc1[1] = defspc1[2] = 0;
  425.  
  426.     world->num_DESC++;
  427.  
  428.     while (len>0) {
  429.         get_name(name, 4, world);
  430.         size = get_ULONG(world);
  431.         len -= 8;
  432.         if (strcmp(name, "NAME")==0) {
  433.             get_name(desc->name, 18, world);
  434.         } else
  435.         if (strcmp(name, "SHAP")==0) {
  436.             if (!desc->shap) {
  437.                 if (!(desc->shap=(WORD*)malloc(2*sizeof(WORD))))
  438.                     { OUT_MEM("SHAP"); }
  439.                 desc->shap[0] = 1;  /* TS defaults */
  440.                 desc->shap[1] = 0;
  441.             }
  442.             desc->shap[0] = get_UWORD(world);
  443.             desc->shap[1] = get_UWORD(world);
  444.         } else
  445.         if (strcmp(name, "POSI")==0) {
  446.             if (!desc->posi) {
  447.                 if (!(desc->posi=(XYZ_st*)malloc(sizeof(XYZ_st))))
  448.                     { OUT_MEM("POSI"); }
  449.             }
  450.             stuff_XYZ(desc->posi, world);
  451.         } else
  452.         if (strcmp(name, "AXIS")==0) {
  453.             if (!desc->axis) {
  454.                 if (!(desc->axis=(AXIS*)malloc(sizeof(AXIS))))
  455.                     { OUT_MEM("AXIS"); }
  456.                 bzero((char*)desc->axis, sizeof(AXIS));
  457.                 desc->axis->xaxi.val[0] = 1;
  458.                 desc->axis->yaxi.val[1] = 1;
  459.                 desc->axis->zaxi.val[2] = 1;
  460.             }
  461.             stuff_XYZ(&desc->axis->xaxi, world);
  462.             stuff_XYZ(&desc->axis->yaxi, world);
  463.             stuff_XYZ(&desc->axis->zaxi, world);
  464.         } else
  465.         if (strcmp(name, "SIZE")==0) {
  466.             if (!desc->size) {
  467.                 if (!(desc->size=(XYZ_st*)malloc(sizeof(XYZ_st))))
  468.                     { OUT_MEM("SIZE"); }
  469.             }
  470.             stuff_XYZ(desc->size, world);
  471.         } else
  472.         if (strcmp(name, "PNTS")==0) {
  473.             i = desc->pcount = get_UWORD(world);    /* Number of points */
  474.             if (!(desc->pnts = (XYZ_st*)malloc(desc->pcount*sizeof(XYZ_st))))
  475.                 OUT_MEM("PNTS");
  476.             for (j=0; j<i; j++)
  477.                 { stuff_XYZ(&desc->pnts[j], world); }
  478.         } else
  479.         if (strcmp(name, "EDGE")==0) {
  480.             i = desc->ecount = get_UWORD(world);    /* Number of edges */
  481.             if (!(desc->edge = (UWORD*)malloc(2*desc->ecount*sizeof(UWORD))))
  482.                 OUT_MEM("EDGE");
  483.             for (j=0; j<2*i; j++)
  484.                 { desc->edge[j] = get_UWORD(world); }
  485.         } else
  486.         if (strcmp(name, "FACE")==0) {
  487.             i = get_UWORD(world);                /* Number of faces */
  488.             malloc_arrays(i, desc);
  489.             for (j=0; j<i; j++) {
  490.                 desc->face[3*j]   = get_UWORD(world);
  491.                 desc->face[3*j+1] = get_UWORD(world);
  492.                 desc->face[3*j+2] = get_UWORD(world);
  493.             }
  494.         } else
  495.         if (strcmp(name, "COLR")==0) {
  496.             if (!desc->colr) {
  497.                 if (!(desc->colr = (RGB_st*)malloc(sizeof(RGB_st))))
  498.                     { OUT_MEM("COLR"); }
  499.             }
  500.             fgetc(world->inp);            /* Must be zero */
  501.             stuff_RGB((RGB_st*)&defclst[0], world);
  502.             desc->colr->val[0] = defclst[0];
  503.             desc->colr->val[1] = defclst[1];
  504.             desc->colr->val[2] = defclst[2];
  505.         } else
  506.         if (strcmp(name, "REFL")==0) {
  507.             if (!desc->refl) {
  508.                 if (!(desc->refl = (RGB_st*)malloc(sizeof(RGB_st))))
  509.                     { OUT_MEM("REFL"); }
  510.             }
  511.             fgetc(world->inp);            /* Must be zero */
  512.             stuff_RGB((RGB_st*)&defrlst[0], world);
  513.             desc->refl->val[0] = defrlst[0];
  514.             desc->refl->val[1] = defrlst[1];
  515.             desc->refl->val[2] = defrlst[2];
  516.         } else
  517.         if (strcmp(name, "TRAN")==0) {
  518.             if (!desc->tran) {
  519.                 if (!(desc->tran = (RGB_st*)malloc(sizeof(RGB_st))))
  520.                     { OUT_MEM("TRAN"); }
  521.             }
  522.             fgetc(world->inp);            /* Must be zero */
  523.             stuff_RGB((RGB_st*)&deftlst[0], world);
  524.             desc->tran->val[0] = deftlst[0];
  525.             desc->tran->val[1] = deftlst[1];
  526.             desc->tran->val[2] = deftlst[2];
  527.         } else
  528.         if (strcmp(name, "SPC1")==0) {
  529.             if (!desc->spc1) {
  530.                 if (!(desc->spc1 = (RGB_st*)malloc(sizeof(RGB_st))))
  531.                     { OUT_MEM("SPC1"); }
  532.             }
  533.             fgetc(world->inp);            /* Must be zero */
  534.             stuff_RGB((RGB_st*)&defspc1[0], world);
  535.             desc->spc1->val[0] = defspc1[0];
  536.             desc->spc1->val[1] = defspc1[1];
  537.             desc->spc1->val[2] = defspc1[2];
  538.         } else
  539.         if (strcmp(name, "CLST")==0) {
  540.             i = get_UWORD(world);        /* Number of faces */
  541.             malloc_arrays(i, desc);
  542.             for (j=0; j<i; j++)
  543.                 { stuff_RGB((RGB_st*)&desc->clst[3*j], world); }
  544.         } else
  545.         if (strcmp(name, "RLST")==0) {
  546.             i = get_UWORD(world);        /* Number of faces */
  547.             malloc_arrays(i, desc);
  548.             for (j=0; j<i; j++)
  549.                 { stuff_RGB((RGB_st*)&desc->rlst[3*j], world); }
  550.         } else
  551.         if (strcmp(name, "TLST")==0) {
  552.             i = get_UWORD(world);        /* Number of faces */
  553.             malloc_arrays(i, desc);
  554.             for (j=0; j<i; j++)
  555.                 { stuff_RGB((RGB_st*)&desc->tlst[3*j], world); }
  556.         } else
  557.         if (strcmp(name, "TPAR")==0) {
  558.             if (!desc->tpar) {
  559.                 if (!(desc->tpar=(double*)malloc(16*sizeof(double))))
  560.                     { OUT_MEM("TPAR"); }
  561.                 bzero((char*)desc->tpar, 16*sizeof(double));
  562.             }
  563.             for (i=0; i<16; i++)
  564.                 desc->tpar[i] = get_FRACT(world);
  565.         } else
  566.         if (strcmp(name, "SURF")==0) {
  567.             if (!desc->surf) {
  568.                 if (!(desc->surf=(UBYTE*)malloc(5*sizeof(UBYTE))))
  569.                     { OUT_MEM("SURF"); }
  570.                 bzero((char*)desc->surf, 5*sizeof(UBYTE));
  571.             }
  572.             for (i=0; i<5; i++)
  573.                 desc->surf[i] = get_BYTE(world);
  574.         } else
  575.         if (strcmp(name, "MTTR")==0) {
  576.             if (!desc->mttr) {
  577.                 if (!(desc->mttr=(MTTR*)malloc(sizeof(MTTR))))
  578.                     { OUT_MEM("MTTR"); }
  579.                 bzero((char*)desc->mttr, sizeof(MTTR));
  580.             }
  581.             desc->mttr->type = get_UBYTE(world);
  582.             desc->mttr->indx = (get_UBYTE(world)/100.0)+1.0;
  583.         } else
  584.         if (strcmp(name, "SPEC")==0) {
  585.             if (!desc->spec) {
  586.                 if (!(desc->spec=(UBYTE*)malloc(2*sizeof(UBYTE))))
  587.                     { OUT_MEM("SPEC"); }
  588.                 bzero((char*)desc->spec, 2*sizeof(UBYTE));
  589.             }
  590.             desc->spec[0] = get_UBYTE(world);
  591.             desc->spec[1] = get_UBYTE(world);
  592.         } else
  593.         if (strcmp(name, "PRP0")==0) {
  594.             if (!desc->prp0) {
  595.                 if (!(desc->prp0=(UBYTE*)malloc(6*sizeof(UBYTE))))
  596.                     { OUT_MEM("PRP0"); }
  597.                 bzero((char*)desc->prp0, 6*sizeof(UBYTE));
  598.             }
  599.             for (i=0; i<6; i++)
  600.                 desc->prp0[i] = get_UBYTE(world);
  601.         } else
  602.         if (strcmp(name, "PRP1")==0) {
  603.             if (!desc->prp1) {
  604.                 if (!(desc->prp1=(UBYTE*)malloc(8*sizeof(UBYTE))))
  605.                     { OUT_MEM("PRP1"); }
  606.                 bzero((char*)desc->prp1, 8*sizeof(UBYTE));
  607.             }
  608.             for (i=0; i<8; i++)
  609.                 desc->prp1[i] = get_UBYTE(world);
  610.         } else
  611.         if (strcmp(name, "INTS")==0) {
  612.             if (!desc->ints) {
  613.                 if (!(desc->ints=(double*)malloc(sizeof(double))))
  614.                     { OUT_MEM("INTS"); }
  615.             }
  616.             *desc->ints = get_FRACT(world);
  617.         } else
  618.         if (strcmp(name, "INT1")==0) {
  619.             if (!desc->int1) desc->int1=(RGB_st*)malloc(sizeof(RGB_st));
  620.             if (!desc->int1) { OUT_MEM("INT1"); }
  621.             stuff_RGB(desc->int1, world);
  622.         } else
  623.         if (strcmp(name, "STRY")==0) {
  624.             get_name(desc->stry->path, 18, world);
  625.             stuff_XYZ(&desc->stry->tran, world);
  626.             stuff_XYZ(&desc->stry->rota, world);
  627.             stuff_XYZ(&desc->stry->scal, world);
  628.             desc->stry->info = get_UWORD(world);
  629.         } else {
  630.             fprintf(stderr, "WARNING: I don't know how to process the OBJ sub-sub-chunk: '%s'\n", name);
  631.             for (i=size; i--; ) fgetc(world->inp);                /* Skip this section */
  632.         }
  633.         if ((size % 2) == 1) { fgetc(world->inp); len--; }    /* Skip odd byte */
  634.         len -= size;
  635.     }
  636. }
  637.  
  638.